package com.yuanian.timingwheel.annotation.scan;

import com.yuanian.timingwheel.annotation.TaskHandler;
import com.yuanian.timingwheel.annotation.TimingTask;
import com.yuanian.timingwheel.annotation.TimingTaskAnnoHandler;
import com.yuanian.timingwheel.annotation.TimingTaskType;
import com.yuanian.timingwheel.context.SpringContext;
import com.yuanian.timingwheel.exception.TwException;
import com.yuanian.timingwheel.facade.TwManager;
import com.yuanian.timingwheel.infrastructure.AopTargetUtils;
import com.yuanian.timingwheel.model.task.build.TaskBuilder;
import com.yuanian.timingwheel.respository.po.TaskEntity;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 自动任务扫描器
 */
public class TimingTaskScanner extends TimingTaskAnnoHandler {

    protected void scan() throws Exception {
        //获取TaskHandler注解的类
        Map<String, Object> map = SpringContext.getBeansWithAnnotation(TaskHandler.class);
        //key为任务描述
        Map<String, TaskBuilder> taskBuilderList = new HashMap<>();
        //遍历类
        for (Map.Entry entry : map.entrySet()) {
            //获取动态代理的原对象
            Object obj = AopTargetUtils.getTarget(entry.getValue());
            Class clz = obj.getClass();
            Method[] methods = clz.getDeclaredMethods();
            //遍历方法
            for (Method method : methods) {
                if (method.isAnnotationPresent(TimingTask.class)) {
                    TimingTask timingTask = method.getAnnotation(TimingTask.class);
                    if (timingTask.timingTaskType() == TimingTaskType.AUTO) {//自动任务
                        //获取动态参数解析器
                        String dynamicParamSolver = timingTask.dynamicParamSolver();
                        TaskBuilder taskBuilder = handle(dynamicParamSolver, clz, method, obj, null, TimingTaskType.AUTO);
                        String taskDesc = taskBuilder.taskDesc();
                        if (taskBuilderList.containsKey(taskDesc)) {
                            throw new TwException("自动定时任务：" + taskDesc + "已经存在");
                        } else {
                            taskBuilderList.put(taskBuilder.taskDesc(), taskBuilder);
                        }
                    }
                }
            }
        }
        //数据库中已经存在的自动任务,不存在就删除
        List<TaskEntity> existTaskList = TaskEntity.getAutoTask();
        for (TaskEntity taskEntity : existTaskList) {
            if (!taskBuilderList.containsKey(taskEntity.getTaskDesc())) {
                TaskEntity.delete(taskEntity);
            }
        }

        Set<String> taskDescList = new HashSet<>();
        for (TaskEntity taskEntity : existTaskList) {
            taskDescList.add(taskEntity.getTaskDesc());
        }
        //保存不存在的任务
        for (TaskBuilder taskBuilder : taskBuilderList.values()) {
            if (!taskDescList.contains(taskBuilder.taskDesc())) {
                TwManager.getInstance().saveTask(taskBuilder);
            }
        }
    }

}
